﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Effects.Effects;

namespace Effects.GUI
{
    // Class used as list of all availible effect. Stores all effect currently availible and creates new instances.
    /// <summary>
    ///  Class represents list of effects. And provides creating new instances.
    /// </summary>
    /// <remarks>
    ///  Class is meant to be used as a real library. First you hava to Load it with Type[] of availible effects and than you can just tell the name and
    ///  it returns new instance of specified effect.
    /// </remarks>
    public class EffectLibrary
    {
        /// <summary>
        ///  Array of known effects' names. It corresponds with types memeber: in types[i] is effect with name equal to names[i].
        /// </summary>
        private string[] names;

        /// <summary>
        ///  Gets array of all currentyl availlible effects.
        /// </summary>
        public string[] Names
        {
            get { return names; }
        }

        /// <summary>
        ///  Array of all availible effects
        /// </summary>
        private Type[] types;
        /// <summary>
        ///  Gets or sets list of availible effects.
        /// </summary>
        public Type[] Types
        {
            get { return types; }
            set
            {
                types = value;
                ConstructNames();
            }

        }

        /// <summary>
        ///  Creates new library that will containt effects specified in parameter types.
        /// </summary>
        /// <param name="types"> List of availible effects. </param>
        public EffectLibrary(Type[] types)
        {
            this.types = types;
            ConstructNames();
        }

        /// <summary>
        /// Creates names. Fills names array according to types array.
        /// </summary>
        private void ConstructNames()
        {
            //names = new string[types.Length];
            List<string> namesList = new List<string>();
            for (int i = 0; i < types.Length; i++)
            {
                try
                {
                    Effect e = (Effect)Activator.CreateInstance(types[i]);
                    //names[i] = e.Name;
                    namesList.Add(e.Name);
                }
                catch (System.Reflection.TargetInvocationException)
                {
                    // do nothing
                    // may say to user that class is corrupted.
                }
            }

            names = namesList.ToArray();
        }

         /// <summary>
        ///  Creates new instance of effect with given name
        /// </summary>
        /// <param name="name"> Name of the effect that should be created.</param>
        /// <returns> New instance of sepcified effect or  null if effect is not availible. (library doesn't know the name) </returns>
        public Effect GetEffect(string name)
        {
            int i=0;
            Effect e=null;
            while (i < names.Length && names[i] != name)
                i++;
            if (i == names.Length)
                throw new EffectNotFoundException(name);

            if (names[i] == name)
                e = (Effect)Activator.CreateInstance(types[i]);

            return e;
        }
    }
}
